#include<cppr.hpp>
using namespace std;
class MyException // 异常类，用来记录异常信息
{
protected:
    char msg[100]; // 存放异常信息
public:
    MyException(const char *str)
    {
        if (strlen(str) < 100)
        {
            strcpy(msg, str);
        }
        else
        {
            strcpy(msg, "异常信息过长");
        }
    }
    virtual const char *what() // 返回异常信息
    {
        return msg;
    }
};

class File_Exception : public MyException // 文件异常类
{
private:
    char filename[100];
    char mode[16];

public:
    File_Exception(const char *str, const char *filename, const char *mode) : MyException(str)
    {
        if (strlen(filename) < 100) // 检查文件名长度
        {
            strcpy(this->filename, filename);
        }
        if (strlen(mode) < 16) // 检查模式长度
        {
            strcpy(this->mode, mode);
        }
    }
    const char *what() // 返回异常信息
    {
        char *str = new char[200];
        sprintf(str, "%s 文件名:%s 模式:%s", msg, filename, mode);
        return str;
    }
};

void openfile(const char *filename, const char *mode)
{
    FILE *fp = fopen(filename, mode);
    if (fp == NULL)
    {
        throw File_Exception("打开文件失败", filename, mode);     // 抛出文件异常1 与catch (File_Exception &e)匹配
        throw new File_Exception("打开文件失败", filename, mode); // 抛出文件异常2 与catch (File_Exception *e)匹配 因为new
    }
    else
    {
        cout << "文件打开成功" << endl;
        fclose(fp);
    }
}

int main()
{
    try
    {
        openfile("a.txt", "r");
    }
    catch (File_Exception &e) // 捕获文件异常1
    {
        cout << e.what() << endl;
    }
    catch (File_Exception *e) // 捕获文件异常2
    {
        cout << e->what() << endl;
    }
    return 0;
}